package com.xuhao.examai.application.services.impl;

import com.xuhao.examai.application.services.UserService;
import com.xuhao.examai.domain.models.User;
import com.xuhao.examai.domain.repositories.UserRepository;
import com.xuhao.examai.common.PageResult;
import com.xuhao.examai.exception.BusinessException;
import com.xuhao.examai.exception.NotFoundException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
@Transactional
public class UserServiceImpl implements UserService {

	private final UserRepository userRepository;
	private final PasswordEncoder passwordEncoder;

	@Override
	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
		log.info("加载用户: {}", username);
		return userRepository.findByUsername(username)
				.orElseThrow(() -> new UsernameNotFoundException("用户不存在: " + username));
	}

	@Override
	public User register(User user) {
		log.info("用户注册: {}", user.getUsername());

		if (!user.isValid()) {
			throw new BusinessException("用户数据无效");
		}

		if (userRepository.existsByUsername(user.getUsername())) {
			throw new BusinessException("用户名已存在");
		}

		if (userRepository.existsByEmail(user.getEmail())) {
			throw new BusinessException("邮箱已存在");
		}

		user.setPassword(passwordEncoder.encode(user.getPassword()));
		user.setRole(User.Role.STUDENT); // 默认角色
		user.setIsActive(true);

		return userRepository.save(user);
	}

	@Override
	public User updateProfile(User user) {
		log.info("更新用户信息: {}", user.getId());

		User existingUser = getUserById(user.getId());

		// 更新基本信息，但不更新密码、用户名和角色
		existingUser.setName(user.getName());
		existingUser.setEmail(user.getEmail());
		existingUser.setPhone(user.getPhone());

		// 如果提供了新密码，则更新密码
		if (user.getPassword() != null && !user.getPassword().isEmpty()) {
			existingUser.setPassword(passwordEncoder.encode(user.getPassword()));
		}

		return userRepository.save(existingUser);
	}

	@Override
	public User updateRole(Long userId, User.Role role) {
		log.info("更新用户角色: userId={}, role={}", userId, role);

		User user = getUserById(userId);
		user.setRole(role);

		return userRepository.save(user);
	}

	@Override
	@Transactional(readOnly = true)
	public User getUserById(Long id) {
		log.info("获取用户: {}", id);
		return userRepository.findById(id)
				.orElseThrow(() -> new NotFoundException("用户", id.toString()));
	}

	@Override
	@Transactional(readOnly = true)
	public User getUserByUsername(String username) {
		log.info("根据用户名获取用户: {}", username);
		return userRepository.findByUsername(username)
				.orElseThrow(() -> new NotFoundException("用户", username));
	}

	@Override
	@Transactional(readOnly = true)
	public User getUserByEmail(String email) {
		log.info("根据邮箱获取用户: {}", email);
		return userRepository.findByEmail(email)
				.orElseThrow(() -> new NotFoundException("用户", email));
	}

	@Override
	@Transactional(readOnly = true)
	public List<User> getAllUsers() {
		log.info("获取所有用户");
		return userRepository.findAll();
	}

	@Override
	@Transactional(readOnly = true)
	public PageResult<User> getUsersByPage(Integer current, Integer size, String keyword, String role) {
		log.info("分页查询用户: current={}, size={}, keyword={}, role={}", current, size, keyword, role);

		// 计算偏移量
		int offset = (current - 1) * size;

		List<User> users;
		long total;

		if (keyword != null && !keyword.trim().isEmpty()) {
			if (role != null && !role.trim().isEmpty()) {
				// 按角色和关键字查询
				users = userRepository.findByRoleAndKeyword(role, keyword.trim());
				total = users.size();
			} else {
				// 只按关键字查询
				users = userRepository.findByKeyword(keyword.trim());
				total = users.size();
			}
		} else if (role != null && !role.trim().isEmpty()) {
			// 只按角色查询
			users = userRepository.findByRole(role);
			total = users.size();
		} else {
			// 查询所有用户
			users = userRepository.findAll();
			total = users.size();
		}

		// 手动分页
		int endIndex = Math.min(offset + size, users.size());
		int startIndex = Math.min(offset, users.size());

		if (startIndex >= users.size()) {
			users = List.of();
		} else {
			users = users.subList(startIndex, endIndex);
		}

		return PageResult.of(users, total, current, size);
	}

	@Override
	@Transactional(readOnly = true)
	public List<User> getUsersByRole(User.Role role) {
		log.info("根据角色获取用户: {}", role);
		return userRepository.findByRole(role.name());
	}

	@Override
	public void deleteUser(Long id) {
		log.info("删除用户: {}", id);

		if (!userRepository.existsById(id)) {
			throw new NotFoundException("用户", id.toString());
		}
		userRepository.deleteById(id);
	}

	@Override
	public User toggleUserStatus(Long userId) {
		log.info("切换用户状态: {}", userId);

		User user = getUserById(userId);
		user.setIsActive(!user.getIsActive());

		return userRepository.save(user);
	}

	@Override
	public User resetPassword(Long userId, String newPassword) {
		log.info("重置用户密码: {}", userId);

		User user = getUserById(userId);
		user.setPassword(passwordEncoder.encode(newPassword));

		return userRepository.save(user);
	}

	@Override
	public User updateAvatar(Long userId, String avatarUrl) {
		log.info("更新用户头像: userId={}", userId);

		User user = getUserById(userId);
		user.setAvatar(avatarUrl);

		return userRepository.save(user);
	}

	@Override
	@Transactional(readOnly = true)
	public boolean existsByUsername(String username) {
		return userRepository.existsByUsername(username);
	}

	@Override
	@Transactional(readOnly = true)
	public boolean existsByEmail(String email) {
		return userRepository.existsByEmail(email);
	}

	@Override
	public void updateLastLoginTime(Long userId) {
		log.info("更新用户最后登录时间: {}", userId);

		User user = getUserById(userId);
		user.updateLastLoginTime();
		userRepository.save(user);
	}
}